﻿/**	@file		ctrl_string.h
 *	@date		(2010-05-16 23:35:05)/(2012-03-18 12:34:22)
 *-----------------------------------------------------------------------------
 *	@version	1.0.2.5
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__LXUT__CTRL_STRING__H__NICK__K_IN_G__)
#define		__LOLIX__LXUT__CTRL_STRING__H__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
#	include	"../../lolix/lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
#	include	"../../lolix/lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_INSTANCE__K_IN_G__)
#	include	"../../lolix/lolix_inst.h"
#endif	//	!defined(__LOLIX__LOLIX_INSTANCE__K_IN_G__)

namespace lxut{namespace ctrl{
	class ctrl_string;
	class ctrl_string_factory;
}}


class LOLIX_NO_VTABLE lxut::ctrl::ctrl_string_factory
	: public lolix::lolix_factory
{
public:
	LOLIX_DECLARE_ITF(lxut::ctrl::ctrl_string_factory, lolix::lolix_factory, (0xe5a8a92e, 0x2d364b68, 0x95cfb538, 0x6dea8fd8));
	LOLIX_INTERFACE(create_inst	, LOLIX_RETNV	, (itf** out_ptr, LOLIX_ITF_ID const* in_id, lolix::lolix_inst* invoked_inst));
	LOLIX_INTERFACE(get_itfs	, size_type		, (LOLIX_ITF_ID const** out_itfs)const);
	LOLIX_INTERFACE(create_inst	, LOLIX_RETNV	, (ctrl_string**, wchar_t const* fmt, size_type fmt_len, bool load_def_fmt_plugin));
};


class LOLIX_NO_VTABLE lxut::ctrl::ctrl_string
	: public lolix::itf
{
public:
	typedef ctrl_string_factory	factory_type;
	LOLIX_DECLARE_ITF(lxut::ctrl::ctrl_string, lolix::itf, (0xd8684659, 0x0b9441bb, 0xae3a2389, 0x4b79f273));
	typedef size_type (LOLIX_CALL *PFN_FMTCALLBACK)(wchar_t const* type, wchar_t* buf, size_type buf_len, size_type max_len, bool left_align, const void* dat);
	LOLIX_INTERFACE(set_plg	, lolix::LOLIX_RETNV , (lolix::lx_u32* id, wchar_t const* type, PFN_FMTCALLBACK plg));
	LOLIX_INTERFACE(find_plg, lolix::LOLIX_RETNV , (lolix::lx_u32* id, wchar_t const* type, size_type type_len)const);
	LOLIX_INTERFACE(set_fmt	, lolix::LOLIX_RETNV , (wchar_t const* fmt, size_type fmt_len));
	LOLIX_INTERFACE(replace	, lolix::LOLIX_RETNV , (size_type idx, const void* dat, lolix::lx_u32 tid));
	LOLIX_INTERFACE(result	, size_type			 , (wchar_t const**)const);
	LOLIX_INTERFACE(clear	, void				 , (void));

	LOLIX_INLINE_CALL wchar_t const* result(void)const
	{
		const wchar_t* dat;
		this->result(&dat);
		return dat;
	}

	LOLIX_INLINE_CALL lolix::LOLIX_RETNV replace(size_type idx, const void* dat)
	{ return this->replace(idx, dat, 0); }

	template<typename _Ty>
	LOLIX_INLINE_CALL lolix::LOLIX_RETNV replace(size_type idx, const void* dat, _Ty type, char (*)[lolix::type::type_equal<_Ty, const wchar_t*>::value] = 0)
	{
		lolix::lx_u32 tid = 0;
		while ( type[tid++] ) (void)0;
		lolix::LOLIX_RETNV rtv;
		if ( LOLIX_CHECK_ERROR(rtv = this->find_plg(&tid, type, tid)) )
			return rtv;
		return this->replace(idx, dat, tid);
	}
	template<typename _Ty, lolix::size_type _Dim>
	LOLIX_INLINE_CALL lolix::LOLIX_RETNV replace(size_type idx, const void* dat, _Ty (&type)[_Dim], char (*)[lolix::type::type_equal<_Ty, const wchar_t>::value] = 0)
	{
		lolix::lx_u32 tid;
		lolix::LOLIX_RETNV rtv;
		if ( LOLIX_CHECK_ERROR(rtv = this->find_plg(&tid, type, _Dim)) )
			return rtv;
		return this->replace(idx, dat, tid);
	}

#define	__LOLIX_TMP__DEF__(type, type_name)	LOLIX_INLINE_CALL lolix::LOLIX_RETNV replace(size_type idx, type dat){ type d(dat); return this->replace(idx, &d, type_name); }
	__LOLIX_TMP__DEF__(lolix::lx_i32, L"i32");
	__LOLIX_TMP__DEF__(lolix::lx_u32, L"u32");
	__LOLIX_TMP__DEF__(lolix::lx_i64, L"i64");
	__LOLIX_TMP__DEF__(lolix::lx_u64, L"u64");

#undef	__LOLIX_TMP__DEF__
#define	__LOLIX_TMP__DEF__(type, type_name)	LOLIX_INLINE_CALL lolix::LOLIX_RETNV replace(size_type idx, type dat){ return this->replace(idx, dat, type_name); }
	__LOLIX_TMP__DEF__(const wchar_t*, L"s");
#undef	__LOLIX_TMP__DEF__
};



//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX__LXUT__CTRL_STRING__H__NICK__K_IN_G__)
